/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Lars Vogel <Lars.Vogel@gmail.com> - Bug 430694
 *     Andrey Loskutov <loskutov@gmx.de> - generified interface, bug 461762
 *     Mickael Istria (Red Hat Inc.) - Bug 486901
 *******************************************************************************/

package org.eclipse.ui.views.bookmarkexplorer;

import java.util.ArrayList;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ColumnLayoutData;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.internal.WorkbenchPlugin;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.views.bookmarkexplorer.BookmarkMessages;
import org.eclipse.ui.internal.views.markers.ExtendedMarkersView;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.MarkerTransfer;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.views.navigator.ShowInNavigatorAction;
import org.osgi.framework.FrameworkUtil;

/**
 * Main class for the bookmark navigator for displaying bookmarks on resources
 * and opening an editor on the bookmarked resource when the user commands.
 * <p>
 *
 * @deprecated This view is no longer in use as of Eclipse 3.4. The view
 *             referenced by {@link IPageLayout#ID_BOOKMARKS} is an
 *             {@link ExtendedMarkersView}.
 *             </p>
 *
 *
 * Marked for deletion, see Bug 550439
 *
 * @noreference
 * @noinstantiate This class is not intended to be instantiated by clients.
 * @noextend This class is not intended to be subclassed by clients.
 */
@Deprecated
public class BookmarkNavigator extends ViewPart {
	private Table table;

	private TableViewer viewer;

	private OpenBookmarkAction openAction;

	private CopyBookmarkAction copyAction;

	private PasteBookmarkAction pasteAction;

	private RemoveBookmarkAction removeAction;

	private EditBookmarkAction editAction;

	private SelectAllAction selectAllAction;

	private ShowInNavigatorAction showInNavigatorAction;

	private SortByAction sortByDescriptionAction;

	private SortByAction sortByResourceAction;

	private SortByAction sortByFolderAction;

	private SortByAction sortByLineAction;

	private SortByAction sortByCreationTime;

	private ChangeSortDirectionAction sortAscendingAction;

	private ChangeSortDirectionAction sortDescendingAction;

	private IMemento memento;

	private BookmarkSorter comparator;

	private Clipboard clipboard;

	private final String columnHeaders[] = {
			BookmarkMessages.ColumnIcon_header,
			BookmarkMessages.ColumnDescription_header,
			BookmarkMessages.ColumnResource_header,
			BookmarkMessages.ColumnFolder_header,
			BookmarkMessages.ColumnLocation_header };

	private ColumnLayoutData columnLayouts[] = {
			new ColumnPixelData(16, false, true), new ColumnWeightData(200),
			new ColumnWeightData(75), new ColumnWeightData(150),
			new ColumnWeightData(60) };

	// Persistance tags.
	private static final String TAG_SELECTION = "selection"; //$NON-NLS-1$

	private static final String TAG_ID = "id";//$NON-NLS-1$

	private static final String TAG_MARKER = "marker";//$NON-NLS-1$

	private static final String TAG_RESOURCE = "resource";//$NON-NLS-1$

	private static final String TAG_VERTICAL_POSITION = "verticalPosition";//$NON-NLS-1$

	private static final String TAG_HORIZONTAL_POSITION = "horizontalPosition";//$NON-NLS-1$

	class SortByAction extends Action {

		private int column;

		/**
		 * @param column
		 */
		public SortByAction(int column) {
			this.column = column;
		}

		@Override
		public void run() {
			comparator.setTopPriority(column);
			updateSortState();
			viewer.refresh();
			IDialogSettings workbenchSettings = PlatformUI
					.getDialogSettingsProvider(FrameworkUtil.getBundle(BookmarkNavigator.class)).getDialogSettings();
			IDialogSettings settings = workbenchSettings
					.getSection("BookmarkSortState");//$NON-NLS-1$
			if (settings == null) {
				settings = workbenchSettings.addNewSection("BookmarkSortState");//$NON-NLS-1$
			}
			comparator.saveState(settings);
		}
	}

	class ChangeSortDirectionAction extends Action {

		private int direction;

		/**
		 * @param direction
		 */
		public ChangeSortDirectionAction(int direction) {
			this.direction = direction;
		}

		@Override
		public void run() {
			comparator.setTopPriorityDirection(direction);
			updateSortState();
			viewer.refresh();
			IDialogSettings workbenchSettings = PlatformUI
					.getDialogSettingsProvider(FrameworkUtil.getBundle(BookmarkNavigator.class)).getDialogSettings();
			IDialogSettings settings = workbenchSettings
					.getSection("BookmarkSortState");//$NON-NLS-1$
			if (settings == null) {
				settings = workbenchSettings.addNewSection("BookmarkSortState");//$NON-NLS-1$
			}
			comparator.saveState(settings);
		}
	}

	/**
	 * Creates the bookmarks view.
	 */
	public BookmarkNavigator() {
		super();
	}

	/**
	 * Adds this views contributions to the workbench.
	 */
	void addContributions() {
		ISharedImages sharedImages = PlatformUI.getWorkbench()
				.getSharedImages();

		// Create the actions.
		openAction = new OpenBookmarkAction(this);
		openAction
				.setImageDescriptor(IDEWorkbenchPlugin.getIDEImageDescriptor("elcl16/gotoobj_tsk.png"));//$NON-NLS-1$

		copyAction = new CopyBookmarkAction(this);
		copyAction.setImageDescriptor(sharedImages
				.getImageDescriptor(ISharedImages.IMG_TOOL_COPY));

		pasteAction = new PasteBookmarkAction(this);
		pasteAction.setImageDescriptor(sharedImages
				.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));

		removeAction = new RemoveBookmarkAction(this);
		removeAction.setImageDescriptor(sharedImages
				.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
		removeAction.setDisabledImageDescriptor(sharedImages
				.getImageDescriptor(ISharedImages.IMG_TOOL_DELETE_DISABLED));

		editAction = new EditBookmarkAction(this);

		selectAllAction = new SelectAllAction(this);
		showInNavigatorAction = new ShowInNavigatorAction(getViewSite()
				.getPage(), viewer);

		// initializes action enabled state
		handleSelectionChanged(StructuredSelection.EMPTY);

		// Create dynamic menu mgr.  Dynamic is currently required to
		// support action contributions.
		MenuManager mgr = new MenuManager();
		mgr.setRemoveAllWhenShown(true);
		mgr.addMenuListener(this::fillContextMenu);
		Menu menu = mgr.createContextMenu(viewer.getControl());
		viewer.getControl().setMenu(menu);
		getSite().registerContextMenu(mgr, viewer);

		// Add actions to the local tool bar
		IToolBarManager tbm = getViewSite().getActionBars().getToolBarManager();
		tbm.add(removeAction);
		tbm.add(openAction);
		tbm.update(false);

		// Register with action service.
		IActionBars actionBars = getViewSite().getActionBars();
		actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(),
				copyAction);
		actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(),
				pasteAction);
		actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),
				removeAction);
		actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(),
				selectAllAction);

		// Set the double click action.
		viewer.addOpenListener(event -> openAction.run());
		viewer.addSelectionChangedListener(event -> handleSelectionChanged(event.getStructuredSelection()));
		viewer.getControl().addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				handleKeyPressed(e);
			}
		});
	}

	@Override
	public void createPartControl(Composite parent) {
		clipboard = new Clipboard(parent.getDisplay());
		createTable(parent);
		viewer = new TableViewer(table);
		createColumns();

		comparator = new BookmarkSorter();
		viewer.setContentProvider(new BookmarkContentProvider(this));
		viewer.setLabelProvider(new BookmarkLabelProvider(this));
		viewer.setInput(ResourcesPlugin.getWorkspace().getRoot());
		viewer.setComparator(comparator);

		IDialogSettings workbenchSettings = PlatformUI
				.getDialogSettingsProvider(FrameworkUtil.getBundle(BookmarkNavigator.class)).getDialogSettings();
		IDialogSettings settings = workbenchSettings
				.getSection("BookmarkSortState");//$NON-NLS-1$
		comparator.restoreState(settings);

		addContributions();
		initDragAndDrop();
		createSortActions();
		fillActionBars();
		updateSortState();
		updatePasteEnablement();

		getSite().setSelectionProvider(viewer);

		if (memento != null) {
			restoreState(memento);
		}
		memento = null;

		PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(),
				IBookmarkHelpContextIds.BOOKMARK_VIEW);
	}

	@Override
	public void dispose() {
		if (clipboard != null) {
			clipboard.dispose();
		}
	}

	/**
	 * Notifies this listener that the menu is about to be shown by
	 * the given menu manager.
	 *
	 * @param manager the menu manager
	 */
	void fillContextMenu(IMenuManager manager) {
		manager.add(openAction);
		manager.add(copyAction);
		updatePasteEnablement();
		manager.add(pasteAction);
		manager.add(removeAction);
		manager.add(selectAllAction);
		manager.add(showInNavigatorAction);
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
		manager.add(new Separator());
		manager.add(editAction);
	}

	@Override
	public <T> T getAdapter(Class<T> adapterClass) {
		if (adapterClass == IShowInSource.class) {
			return adapterClass.cast((IShowInSource) () -> new ShowInContext(null, getViewer().getSelection()));
		}
		if (adapterClass == IShowInTargetList.class) {
			return adapterClass.cast((IShowInTargetList) () -> new String[] { IPageLayout.ID_PROJECT_EXPLORER });
		}
		return super.getAdapter(adapterClass);
	}

	/**
	 * Returns the UI plugin for the bookmarks view.
	 */
	static AbstractUIPlugin getPlugin() {
		return WorkbenchPlugin.getDefault();
	}

	/**
	 * Returns the shell.
	 */
	Shell getShell() {
		return getViewSite().getShell();
	}

	/**
	 * Returns the viewer used to display bookmarks.
	 *
	 * @return the viewer, or <code>null</code> if this view's controls
	 *  have not been created yet
	 */
	StructuredViewer getViewer() {
		return viewer;
	}

	/**
	 * Returns the workspace.
	 */
	IWorkspace getWorkspace() {
		return ResourcesPlugin.getWorkspace();
	}

	/**
	 * Handles key events in viewer.
	 */
	void handleKeyPressed(KeyEvent event) {
		if (event.character == SWT.DEL && event.stateMask == 0
				&& removeAction.isEnabled()) {
			removeAction.run();
		}
	}

	/**
	 * Handles a selection change.
	 *
	 * @param selection the new selection
	 */
	void handleSelectionChanged(IStructuredSelection selection) {
		//update the actions
		openAction.selectionChanged(selection);
		removeAction.selectionChanged(selection);
		editAction.selectionChanged(selection);
		selectAllAction.selectionChanged(selection);
		showInNavigatorAction.selectionChanged(selection);
	}

	@Override
	public void init(IViewSite site, IMemento memento) throws PartInitException {
		super.init(site, memento);
		this.memento = memento;
	}

	/**
	 * Adds drag and drop support to the bookmark navigator.
	 */
	protected void initDragAndDrop() {
		int operations = DND.DROP_COPY;
		Transfer[] transferTypes = new Transfer[] {
				MarkerTransfer.getInstance(), TextTransfer.getInstance() };
		DragSourceListener listener = new DragSourceAdapter() {
			@Override
			public void dragSetData(DragSourceEvent event) {
				performDragSetData(event);
			}

			@Override
			public void dragFinished(DragSourceEvent event) {
			}
		};
		viewer.addDragSupport(operations, transferTypes, listener);
	}

	/**
	 * The user is attempting to drag marker data.  Add the appropriate
	 * data to the event depending on the transfer type.
	 */
	void performDragSetData(DragSourceEvent event) {
		if (MarkerTransfer.getInstance().isSupportedType(event.dataType)) {
			event.data = viewer.getStructuredSelection().toArray();
			return;
		}
		if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
			Object[] markers = viewer.getStructuredSelection().toArray();
			if (markers != null) {
				StringBuilder buffer = new StringBuilder();
				ILabelProvider provider = (ILabelProvider) getViewer()
						.getLabelProvider();
				for (int i = 0; i < markers.length; i++) {
					if (i > 0) {
						buffer.append(System.lineSeparator());
					}
					String text = provider.getText(markers[i]);
					if(text != null) {
						buffer.append(text);
					}
				}
				event.data = buffer.toString();
			}
			return;
		}
	}

	void restoreState(IMemento memento) {
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IMemento selectionMem = memento.getChild(TAG_SELECTION);
		if (selectionMem != null) {
			ArrayList<IMarker> selectionList = new ArrayList<>();
			for (IMemento markerMem : selectionMem.getChildren(TAG_MARKER)) {
				try {
					long id = Long.parseLong(markerMem.getString(TAG_ID));
					IResource resource = root.findMember(markerMem
							.getString(TAG_RESOURCE));
					if (resource != null) {
						IMarker marker = resource.findMarker(id);
						if (marker != null) {
							selectionList.add(marker);
						}
					}
				} catch (CoreException e) {
				}
			}
			viewer.setSelection(new StructuredSelection(selectionList));
		}

		Scrollable scrollable = (Scrollable) viewer.getControl();
		//save vertical position
		ScrollBar bar = scrollable.getVerticalBar();
		if (bar != null) {
			try {
				String posStr = memento.getString(TAG_VERTICAL_POSITION);
				int position;
				position = Integer.parseInt(posStr);
				bar.setSelection(position);
			} catch (NumberFormatException e) {
			}
		}
		bar = scrollable.getHorizontalBar();
		if (bar != null) {
			try {
				String posStr = memento.getString(TAG_HORIZONTAL_POSITION);
				int position;
				position = Integer.parseInt(posStr);
				bar.setSelection(position);
			} catch (NumberFormatException e) {
			}
		}

		updateSortState();
		viewer.refresh();
	}

	@Override
	public void saveState(IMemento memento) {
		if (viewer == null) {
			if (this.memento != null) {
				memento.putMemento(this.memento);
			}
			return;
		}

		Scrollable scrollable = (Scrollable) viewer.getControl();
		Object markers[] = viewer.getStructuredSelection().toArray();
		if (markers.length > 0) {
			IMemento selectionMem = memento.createChild(TAG_SELECTION);
			for (Object currentMarker : markers) {
				IMemento elementMem = selectionMem.createChild(TAG_MARKER);
				IMarker marker = (IMarker) currentMarker;
				elementMem.putString(TAG_RESOURCE, marker.getResource().getFullPath().toString());
				elementMem.putString(TAG_ID, String.valueOf(marker.getId()));
			}
		}

		//save vertical position
		ScrollBar bar = scrollable.getVerticalBar();
		int position = bar != null ? bar.getSelection() : 0;
		memento.putString(TAG_VERTICAL_POSITION, String.valueOf(position));
		//save horizontal position
		bar = scrollable.getHorizontalBar();
		position = bar != null ? bar.getSelection() : 0;
		memento.putString(TAG_HORIZONTAL_POSITION, String.valueOf(position));

	}

	@Override
	public void setFocus() {
		if (viewer != null) {
			viewer.getControl().setFocus();
		}
	}

	void createColumns() {
		SelectionListener headerListener = new SelectionAdapter() {
			/**
			 * Handles the case of user selecting the
			 * header area.
			 * <p>If the column has not been selected previously,
			 * it will set the sorter of that column to be
			 * the current tasklist sorter. Repeated
			 * presses on the same column header will
			 * toggle sorting order (ascending/descending).
			 */
			@Override
			public void widgetSelected(SelectionEvent e) {
				// column selected - first column doesn't count
				int column = table.indexOf((TableColumn) e.widget) - 1;
				if (column == comparator.getTopPriority()) {
					comparator.reverseTopPriority();
				} else {
					comparator.setTopPriority(column);
				}
				updateSortState();
				viewer.refresh();
				IDialogSettings workbenchSettings = PlatformUI
						.getDialogSettingsProvider(FrameworkUtil.getBundle(BookmarkNavigator.class))
						.getDialogSettings();
				IDialogSettings settings = workbenchSettings
						.getSection("BookmarkSortState");//$NON-NLS-1$
				if (settings == null) {
					settings = workbenchSettings
							.addNewSection("BookmarkSortState");//$NON-NLS-1$
				}
				comparator.saveState(settings);
			}
		};

		TableLayout layout = new TableLayout();
		table.setLayout(layout);
		table.setHeaderVisible(true);
		for (int i = 0; i < columnHeaders.length; i++) {
			layout.addColumnData(columnLayouts[i]);
			TableColumn tc = new TableColumn(table, SWT.NONE, i);
			tc.setResizable(columnLayouts[i].resizable);
			tc.setText(columnHeaders[i]);
			if (i > 0) {
				tc.addSelectionListener(headerListener);
			}
		}
	}

	/**
	 * Creates the table control.
	 */
	void createTable(Composite parent) {
		table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
				| SWT.FULL_SELECTION);
		table.setLinesVisible(true);
		//table.setLayout(new TableLayout());
	}

	/**
	 * Fills the local tool bar and menu manager with actions.
	 */
	void fillActionBars() {
		IActionBars actionBars = getViewSite().getActionBars();
		IMenuManager menu = actionBars.getMenuManager();
		IMenuManager submenu = new MenuManager(BookmarkMessages.SortMenuGroup_text);
		menu.add(submenu);
		submenu.add(sortByDescriptionAction);
		submenu.add(sortByResourceAction);
		submenu.add(sortByFolderAction);
		submenu.add(sortByLineAction);
		submenu.add(sortByCreationTime);
		submenu.add(new Separator());
		submenu.add(sortAscendingAction);
		submenu.add(sortDescendingAction);
	}

	void createSortActions() {
		sortByDescriptionAction = new SortByAction(BookmarkSorter.DESCRIPTION);
		sortByDescriptionAction.setText(BookmarkMessages.ColumnDescription_text);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(
				sortByDescriptionAction,
				IBookmarkHelpContextIds.SORT_DESCRIPTION_ACTION);

		sortByResourceAction = new SortByAction(BookmarkSorter.RESOURCE);
		sortByResourceAction.setText(BookmarkMessages.ColumnResource_text);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByResourceAction,
				IBookmarkHelpContextIds.SORT_RESOURCE_ACTION);

		sortByFolderAction = new SortByAction(BookmarkSorter.FOLDER);
		sortByFolderAction.setText(BookmarkMessages.ColumnFolder_text);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByFolderAction,
				IBookmarkHelpContextIds.SORT_FOLDER_ACTION);

		sortByLineAction = new SortByAction(BookmarkSorter.LOCATION);
		sortByLineAction.setText(BookmarkMessages.ColumnLocation_text);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByLineAction,
				IBookmarkHelpContextIds.SORT_LOCATION_ACTION);

		sortByCreationTime = new SortByAction(BookmarkSorter.CREATION_TIME);
		sortByCreationTime.setText(BookmarkMessages.ColumnCreationTime_text);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(sortByCreationTime,
				IBookmarkHelpContextIds.SORT_CREATION_TIME_ACTION);

		sortAscendingAction = new ChangeSortDirectionAction(
				BookmarkSorter.ASCENDING);
		sortAscendingAction.setText(BookmarkMessages.SortDirectionAscending_text);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(sortAscendingAction,
				IBookmarkHelpContextIds.SORT_ASCENDING_ACTION);

		sortDescendingAction = new ChangeSortDirectionAction(
				BookmarkSorter.DESCENDING);
		sortDescendingAction.setText(BookmarkMessages.SortDirectionDescending_text);
		PlatformUI.getWorkbench().getHelpSystem().setHelp(sortDescendingAction,
				IBookmarkHelpContextIds.SORT_DESCENDING_ACTION);
	}

	void updateSortState() {
		int column = comparator.getTopPriority();
		sortByDescriptionAction
				.setChecked(column == BookmarkSorter.DESCRIPTION);
		sortByResourceAction.setChecked(column == BookmarkSorter.RESOURCE);
		sortByFolderAction.setChecked(column == BookmarkSorter.FOLDER);
		sortByLineAction.setChecked(column == BookmarkSorter.LOCATION);
		sortByCreationTime.setChecked(column == BookmarkSorter.CREATION_TIME);

		int direction = comparator.getTopPriorityDirection();
		sortAscendingAction.setChecked(direction == BookmarkSorter.ASCENDING);
		sortDescendingAction.setChecked(direction == BookmarkSorter.DESCENDING);
	}

	/**
	 * Updates the enablement of the paste action
	 */
	void updatePasteEnablement() {
		// Paste if clipboard contains tasks
		MarkerTransfer transfer = MarkerTransfer.getInstance();
		IMarker[] markerData = (IMarker[]) getClipboard().getContents(transfer);
		boolean canPaste = false;
		if (markerData != null) {
			for (IMarker marker : markerData) {
				try {
					if (marker.getType().equals(IMarker.BOOKMARK)) {
						canPaste = true;
						break;
					}
				} catch (CoreException e) {
					canPaste = false;
				}
			}
		}
		pasteAction.setEnabled(canPaste);
	}

	Clipboard getClipboard() {
		return clipboard;
	}

}

